/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bff.core.action.retrieve;

import com.inspur.edp.bff.api.exception.BffFrameworkException;
import com.inspur.edp.bff.api.exception.ErrorCodes;
import com.inspur.edp.bff.api.param.retrieve.RetrieveParam;
import com.inspur.edp.bff.api.param.retrieve.RetrieveResult;
import com.inspur.edp.bff.spi.AbstractFSAction;
import com.inspur.edp.cef.entity.dependenceTemp.Pagination;
import com.inspur.edp.cef.entity.entity.IEntityData;
import com.inspur.edp.cef.entity.entity.IEntityDataCollection;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class RetrieveWithChildPaginationAction extends AbstractFSAction<RetrieveResult> {
    private String dataId;
    private RetrieveParam param;

    public RetrieveWithChildPaginationAction(String dataId, RetrieveParam param) {
        this.dataId = dataId;
        this.param = param;
    }

    @Override
    protected void execute() {
        if (param == null)
            throw new BffFrameworkException(ErrorCodes.BFF_FRAMEWORK_1013);
        if (dataId == null || "".equals(dataId))
            throw new BffFrameworkException(ErrorCodes.BFF_FRAMEWORK_1014);
        IEntityData entityData = getContext().getBffManager().retrieve(dataId);
        if (entityData == null)
            return;
        HashMap<String, Pagination> pageResult = new HashMap<>();
        BuildChildData(entityData, param, dataId, pageResult);
        setResult(getRetrieveResult(entityData, pageResult));
    }

    private void BuildChildData(IEntityData baseData, RetrieveParam params, String id, HashMap<String, Pagination> pageResult) {
        HashMap<String, IEntityDataCollection> entityDatas = baseData.getChilds();
        IEntityDataCollection childData = null;

        for (String frontKey : params.getFilters().keySet()) {
            String voKey = getContext().getVoCode(frontKey);
            childData = entityDatas.get(voKey);
            if (childData == null || childData.size() <= 0) {
                continue;
            }
            Pagination pagination = params.getFilters().get(frontKey).getPagination();
            if (pagination.getPageSize() == 0)//分页个数=0时要求返回所有
            {
                continue;
            }
            if (pagination.getPageIndex() <= 0) {
                throw new BffFrameworkException(ErrorCodes.BFF_FRAMEWORK_1015);
            }
            int pageIndex = pagination.getPageIndex();
            int pageSize = pagination.getPageSize();
            Pagination pagination1 = new Pagination();
            pagination1.setPageIndex(pageIndex);
            pagination1.setPageSize(pageSize);
            pagination1.setTotalCount(childData.size());
            int realPageCount = (int) Math.ceil((float) childData.size() / pageSize);
            if (pageIndex > realPageCount) {
                pageIndex = realPageCount;
            }
            int otherCount = childData.size() - (pageIndex - 1) * pageSize;
            int pageCount = pageIndex * pageSize;
            if (otherCount < pageSize) {
                pageCount = childData.size();
            }
            List<IEntityData> childDataNews = new ArrayList<IEntityData>(childData).subList((pageIndex - 1) * pageSize, pageCount);
            childData.clear();
            baseData.mergeChildData(voKey, new ArrayList<>(childDataNews));
            pageResult.put(frontKey + "_" + id, pagination1);

        }
        for (IEntityDataCollection datas : entityDatas.values()) {
            for (IEntityData data : datas) {
                BuildChildData(data, params, data.getID(), pageResult);
            }
        }
    }

    private RetrieveResult getRetrieveResult(IEntityData baseData, HashMap<String, Pagination> pageResult) {
        RetrieveResult retrieveResult = new RetrieveResult();
        retrieveResult.setResult(baseData);
        retrieveResult.setPagination(pageResult);
        return retrieveResult;
    }
}
